﻿using System;
using System.Collections.Generic;

namespace Simp.CodeModel.CoreFunctions
{
	/// <summary>Encapsulates the negation of a function.</summary>
	/// <remarks>
	/// If the parameter is a number
	/// (e.g. <see cref="IntegerFunction"/> or <see cref="DoubleFunction"/>), the negation can be done as a simplification.
	/// </remarks>
	public class NegativeFunction : IFunction, IFunctionSerializer
	{
		private static readonly string[] _parameterNames = new string[] { "function" };

		#region IFunction Members
		string IFunction.FunctionName
		{
			get { return "Negative"; }
		}

		string[] IFunction.ParameterNames
		{
			get { return _parameterNames; }
		}

		IFunctionParameterBinding[] IFunction.DefaultParameterValues
		{
			get { return FunctionHelper.EmptyBindings; }
		}

		IFunction IFunction.Simplify(SimplificationMode simplificationMode, IFunction[] parameters)
		{
			FunctionHelper.ValidateParameters(this, parameters);

			IFunction innerFunction = parameters[0];
			RealFunction realExpression = innerFunction as RealFunction;

			if (realExpression != null)
			{
				return new RealFunction(-realExpression.Value);
			}
			else
			{
				IntegerFunction integerExpression = innerFunction as IntegerFunction;

				if (integerExpression != null)
				{
					return new IntegerFunction(-integerExpression.Value);
				}
				else
				{
					return null;
				}
			}
		}

		IFunction IFunction.AcceptVisitor(IFunctionVisitor visitor)
		{
			return null;
		}
		#endregion

		#region IFunctionSerializer Members
		void IFunctionSerializer.Serialize(AppendOnlyStringBuilder builder, params IFunction[] parameters)
		{
			FunctionHelper.ValidateParameters(this, parameters);

			builder.Append("-");
			FunctionHelper.Serialize(parameters[0], builder);
		}
		#endregion
	}
}